import asyncio
import json
import sys
import os
import time
import threading
from multiprocessing import Process
from pathlib import Path

import websockets
from util import is_port_in_use, get_status,send_redis_set
from json_flask import JsonFlask
from json_response import JsonResponse
from flask import request
from pcap_server import pcap_run
from rtsp_server import video_run
import redis

app = JsonFlask(__name__)

PENDING = 'pending'
SUCCESS = 'success'
ERROR = 'error'

process_dist = dict()

clients = {}  # 用于存储每个客户端的WebSocket连接# # 存储 WebSocket 连接端的字典
# websocket_connections = dict()
# client_timestamp_dict = dict()
data_received = {}  # 用于存储每个客户端发送的数据
lock = asyncio.Lock()  # 用于同步访问字典

pcap_num = 0
video_num = 0
config_json = None


def get_config_json(config_path):
    global config_json, pcap_num, video_num
    with open(config_path, 'r', encoding='utf-8') as f:
        init_data = f.read()
        config_json = json.loads(init_data)
        print(config_json)
        station_num = len(config_json["station"])
        for i in range(station_num):
            pcap_num += len(config_json["station"][i]["pcap"])
            video_num += len(config_json["station"][i]["video"])


@app.route('/startProcess', methods=['Get'])
def startProcess():
    """
    同时启动pcap和video进程
    """
    global config_json
    pcap_process = Process(target=pcap_run, args=(config_json,))
    pcap_process.start()

    video_process = Process(target=video_run, args=(config_json,))
    video_process.start()

    return JsonResponse.success("开启成功")


@app.route('/addDevice', methods=['Post'])
def addDevice():
    """
    新增设备
    :return:
    """
    temp_dict = request.get_json()
    print("param:", temp_dict)
    assert type(temp_dict).__name__ == 'dict', '参数异常'

    """
    1 新增设备时，需要保证新增设备的数据时间戳和已经发送的设备的时间戳一直，如果没有已经在发送的设备，则从最开始的位置发送
    """

    global config_json

    video_process = Process(target=video_run, args=(config_json,))
    video_process.start()

    return JsonResponse.success("开启成功")


@app.route('/getState', methods=['Get'])
def getState():
    """
    得到所有设备的信息
    :return:
    """
    result = get_status()
    return JsonResponse.success(result)


@app.route('/getFolderInfo', methods=['Get'])
def get_folder_info():
    """
    得到离线文件夹的信息
    :return:
    """
    file_path = config_json['file_path']
    result = {}
    root_directory = Path(file_path)
    for item in root_directory.iterdir():
        if item.is_dir():
            s_name = {}
            for s_item in item.iterdir():
                if s_item.is_dir():
                    bin_name = []
                    for t_item in s_item.iterdir():
                        if not t_item.is_dir():
                            print(t_item.name)
                            bin_name.append(t_item.name)
                    s_name[s_item.name] = bin_name
        result[item.name] = s_name

    print(result)
    return JsonResponse.success(result)


@app.errorhandler(Exception)
def error_handler(e):
    """
    全局异常捕获
    """
    return JsonResponse.error(msg=str(e))


async def handle_client(websocket, path):
    async with lock:
        clients[websocket] = []
        data_received[websocket] = []

    # try:
    async for message in websocket:
        data_received[websocket].append(int(message))
        print(f"Received data from {websocket}: {message}")

        clients_list = list(clients.keys())
        print(f"Clients: {clients_list}")
        print("判断长度是否一致", len(clients_list) == (pcap_num + video_num))
        if len(clients_list) == (pcap_num + video_num):
            print("Both clients have sent data, comparing...")
            # 检查字典中所有值是否都不为[]
            all_values_present = all(value != [] for value in data_received.values())
            print("检查字典中所有值是否都不为", all_values_present)
            if all_values_present:
                print("Both clients have sent a single value, comparing...")
                await compare_and_broadcast()
                print("Comparison completed.")
    # finally:
    #     async with lock:
    #         del clients[websocket]
    #         del data_received[websocket]





async def compare_and_broadcast():
    print("Comparing data...")
    max_of_maxes = max(data_received.values(), default=None) if data_received else None
    if max_of_maxes is not None:
        threading.Thread(target=send_redis_set, args=("time_diff", int(time.time() * 1000) - int(max_of_maxes[0]),)).start()
        for ws in clients:
            try:
                await ws.send(str(max_of_maxes[0]))
                print(f"Sent max value to {ws}: {max_of_maxes[0]}")
            except Exception as e:
                print(f"Error sending message: {e}")
        # 在实际应用中，可以在此处添加逻辑判断是否所有客户端已完成交互并关闭服务器


def start_websocket_server():
    # 启动 WebSocket 服务器
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    local_ip = config_json["local_ip"]
    websocket_port = config_json["websocket_port"]
    if local_ip == "127.0.0.1":
        while is_port_in_use(local_ip, websocket_port):
            time.sleep(0.1)
    start_server = websockets.serve(handle_client, local_ip, websocket_port)
    loop.run_until_complete(start_server)
    # loop.run_until_complete(websocket_broadcast())
    loop.run_forever()


def runstart():
    app.run(host='0.0.0.0', port=5003)


def httpserver():
    runstart()


if __name__ == '__main__':
    current_dir = os.path.dirname(os.path.abspath(__file__))
    # parent_dir = os.path.dirname(current_dir)
    config_path = os.path.join(current_dir, 'Conf', 'config.json')
    get_config_json(config_path)
    if config_json is None:
        print("config_json is None")
        sys.exit(1)
    else:
        # 启动 WebSocket 服务器
        websocket_thread = threading.Thread(target=start_websocket_server)
        websocket_thread.start()
        # 启动 Flask 服务器
        httpserver()
